from typing import Type, Tuple

from django.db import models
from django.db.models import Sum, F
from django.http import JsonResponse

from rest_framework import permissions
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticatedOrReadOnly

from library_app.models import Category, Author, Book
from library_app.serializers import CategorySerializer, AuthorSerializer, BookReadSerializer, BookWriteSerializer


class BookViewSet(viewsets.ModelViewSet):
    permission_classes: tuple[Type[IsAuthenticatedOrReadOnly]] = (permissions.IsAuthenticatedOrReadOnly,)
    queryset = Book.objects.all()

    def list(self, request, *args, **kwargs):
        query = self.get_queryset()
        if request.query_params.get('totalnumber') == 'true':
            total = query.aggregate(total=Sum('owned'))
            return JsonResponse({'result of Total number of books owned:': total})
        if request.query_params.get('totalcost') == 'true':
            total = query.aggregate(
                total=Sum(F('price') * F('owned'), output_field=models.FloatField()))
            return JsonResponse({'result of Total cost of all books:': total})
        queryset = self.filter_queryset(query)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    def get_serializer_class(self):
        if self.request.method in ['GET', 'HEAD']:
            return BookReadSerializer
        else:
            return BookWriteSerializer


class CategoryViewSet(viewsets.ModelViewSet):
    permission_classes: tuple[Type[IsAuthenticatedOrReadOnly]] = (permissions.IsAuthenticatedOrReadOnly,)
    queryset = Category.objects.all()

    def list(self, request, *args, **kwargs):
        if request.query_params.get('bookstop') == 'true':
            from django.db import connection
            cursor = connection.cursor()
            cursor.execute(
                'select category_id,max(totalbook) as total from (select category_id,sum(owned) as totalbook from library_app_book group by category_id)')
            ret = cursor.fetchall()
            return JsonResponse({'result of Category with most books[category_id,ownedbookstotal]': ret})
        query = self.get_queryset()
        queryset = self.filter_queryset(query)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    def get_serializer_class(self):
        return CategorySerializer
    

class AuthorViewSet(viewsets.ModelViewSet):
    permission_classes: tuple[Type[IsAuthenticatedOrReadOnly]] = (permissions.IsAuthenticatedOrReadOnly,)
    queryset = Author.objects.all()

    def list(self, request, *args, **kwargs):
        if request.query_params.get('bookstop') == 'true':
            from django.db import connection
            cursor = connection.cursor()
            cursor.execute(
                'select author_id,max(totalbook) as total from (select id,author_id,sum(owned) as totalbook from library_app_book group by author_id) ')
            ret = cursor.fetchall()
            return JsonResponse({'result of Author with most books[author_id,ownedbookstotal]': ret})
        query = self.get_queryset()
        queryset = self.filter_queryset(query)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    def get_serializer_class(self):
        return AuthorSerializer
